#ifndef COMPONENTMANAGER_H_
#define COMPONENTMANAGER_H_


#include <string>

#include "AI/Messaging/Telegram.h"
#include "LibraryFrameworkExport.h"
#include "Game/GameTime.h"
#include <iosfwd>
#include "Component.h"
#include <vector>
#include "EventHandler/EventHandler.h"

namespace CasaEngine
{
	class BaseEntity;

	/*
	 *	
	 */
	class LIBRARY_FRAMEWORK_EXPORT ComponentManager
	{

	private:
		BaseEntity* m_pEntity;
		std::vector<Component *> m_Components;

	public:
		ComponentManager(BaseEntity* pEntity_);
		~ComponentManager();

		/**
		 *	Get the first component of type T found
		 */
		template <class T>
		T* GetComponent() const
		{
			for (size_t i=0; i<m_Components.size(); i++)
			{
				T* res = dynamic_cast<T*>(m_Components[i]);

				if (res != NULL)
				{
					return res;
				}
			}

			return NULL;
		}

		/**
		 *	Get the list of all components of type T found
		 */
		template <class T>
		std::vector<T*> GetComponents() const
		{
			std::vector<T*> res;

			for (size_t i=0; i<m_Components.size(); i++)
			{
				T* c = dynamic_cast<T*>(m_Components[i]);

				if (c != NULL)
				{
					res.push_back(c);
				}
			}

			return res;
		}

		//all entities must implement an update function
		void  Update(const GameTime& gameTime_);
		//all entities must implement an update function
		//void  Draw();
		
		/**
		 * 
		 */
		void AddComponent(Component* m_pComponent_);

		/**
		 * 
		 */
		void RemoveComponent( Component* m_pComponent_ );

		/**
		 * 
		 */
		void HandleEvent(const Event* pEvent_);

		/**
		 * 
		 */
		BaseEntity* GetEntity() const;
		//entities should be able to read/write their data to a stream
		virtual void Write(std::ostream&  os)const;
		virtual void Read (std::ifstream& is);

		/**
		 * 
		 */
		void InitializeComponents();
		bool HandleMessage( const Telegram& msg );
	};

}

#endif // COMPONENTMANAGER_H_


